<template>
  <common-edit-dialog
    :title="title"
    :visible.sync="open"
    @cancel="cancel"
    @submit="submitForm"
    width="700px"
    :buttonLoading="buttonLoading"
  >
    <el-form
      ref="form"
      :model="form"
      :rules="rules"
      label-width="80px"
      @submit.native.prevent
    >
      <el-row>
        <el-col :span="24">
          <el-form-item label="任务名称" prop="nmapName">
            <common-input
              v-model="form.nmapName"
              :verify="false"
              :maxlength="32"
              placeholder="请输入"
            />
          </el-form-item>
        </el-col>

        <!-- <el-col :span="24">
          <el-form-item label="扫描方式" prop="scanType">
            <el-select v-model="form.scanType" filterable clearable>
              <el-option label="主机扫描" value="0"></el-option>
              <el-option label="端口扫描" value="1"></el-option>
            </el-select>
          </el-form-item>
        </el-col> -->

        <el-col :span="24">
          <el-form-item label="IP段" prop="nmapIps" class="taskItem">
            <common-input
              v-model="form.nmapIps"
              :verify="false"
              :maxlength="128"
              placeholder="请输入"
            />
            <content-tip
              :tipType="'ip_segment'"
              :popoverWidth="'280'"
            ></content-tip>
          </el-form-item>
        </el-col>

        <!-- <el-col :span="24" v-if="this.form.scanType === '1'">
          <el-form-item label="端口段" prop="nmapPorts" class="taskItem">
            <common-input v-model="form.nmapPorts" placeholder="请输入" />
            <content-tip
              :tipType="'port_segment'"
              :popoverWidth="'200'"
            ></content-tip>
          </el-form-item>
        </el-col> -->

        <el-col :span="12">
          <el-form-item label="执行周期" prop="jobCycle">
            <el-select
              v-model="form.jobCycle"
              placeholder="请选择"
              @change="changeType"
            >
              <el-option
                v-for="item in executionCycleTypeArr"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>

        <el-col :span="12" style="display: flex">
          <el-form-item
            prop="cycleTime"
            v-if="form.jobCycle === '1'"
            label-width="0"
            style="margin-left: 30px; width: 100%"
          >
            <el-date-picker
              v-model="form.cycleTime"
              :picker-options="pickerTimeOptions"
              type="datetime"
              placeholder="请选择时间"
              value-format="yyyy-MM-dd HH:mm:ss"
              format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              popper-class="subs-time-popper"
              @change="checkValidate('cycleTime')"
            >
            </el-date-picker>
          </el-form-item>

          <!-- 2 按日 -->
          <el-form-item
            prop="cycleDay"
            v-if="form.jobCycle === '2'"
            label-width="0"
            class="by-day-execute"
          >
            <el-time-picker
              v-model="form.cycleDay"
              :picker-options="pickerOptions"
              placeholder="请选择时间"
              value-format="HH:mm"
              format="HH:mm"
              style="width: 100%"
              @change="checkValidate('cycleDay')"
            >
            </el-time-picker>
          </el-form-item>

          <!-- 3 按周 -->
          <el-form-item
            prop="weekDay"
            v-if="form.jobCycle === '3'"
            label-width="30px"
            style="width: 50%"
          >
            <el-select
              v-model="form.weekDay"
              placeholder="请选择"
              style="width: 100%"
              @change="checkValidate('weekDay')"
            >
              <el-option label="星期一" value="1" />
              <el-option label="星期二" value="2" />
              <el-option label="星期三" value="3" />
              <el-option label="星期四" value="4" />
              <el-option label="星期五" value="5" />
              <el-option label="星期六" value="6" />
              <el-option label="星期日" value="7" />
            </el-select>
          </el-form-item>

          <el-form-item
            style="width: 50%"
            prop="cycleWeek"
            v-if="form.jobCycle === '3'"
            label-width="0"
          >
            <el-time-picker
              v-model="form.cycleWeek"
              :picker-options="pickerOptions"
              placeholder="请选择时间"
              value-format="HH:mm"
              format="HH:mm"
              style="width: 100%"
              @change="checkValidate('cycleWeek')"
            >
            </el-time-picker>
          </el-form-item>

          <!-- 4 按月  -->
          <el-form-item
            prop="monthDay"
            v-if="form.jobCycle === '4'"
            label-width="30px"
            style="width: 50%"
          >
            <el-select
              v-model="form.monthDay"
              placeholder="请选择"
              style="width: 100%"
              clearable
              @change="checkValidate('monthDay')"
            >
              <el-option
                v-for="item in 31"
                :key="item"
                :label="item"
                :value="item"
              />
            </el-select>
          </el-form-item>

          <el-form-item
            prop="cycleMonth"
            v-if="form.jobCycle === '4'"
            label-width="0"
            style="width: 50%"
          >
            <el-time-picker
              v-model="form.cycleMonth"
              :picker-options="pickerOptions"
              placeholder="请选择时间"
              value-format="HH:mm"
              format="HH:mm"
              style="width: 100%"
              @change="checkValidate('cycleMonth')"
            >
            </el-time-picker>
          </el-form-item>

          <!-- 5 按季  -->
          <el-form-item
            prop="quarterDay"
            v-if="form.jobCycle === '5'"
            label-width="0"
            style="margin-left: 30px"
          >
            <MonthDays
              v-model="form.quarterDay"
              :monthDaysOptions="monthDaysOptions"
              @getValue="getQuarterValue"
            />
          </el-form-item>

          <el-form-item
            prop="cycleQuarter"
            v-if="form.jobCycle === '5'"
            label-width="0"
          >
            <el-time-picker
              v-model="form.cycleQuarter"
              :picker-options="pickerOptions"
              placeholder="请选择时间"
              value-format="HH:mm"
              format="HH:mm"
              @change="checkValidate('cycleQuarter')"
            >
            </el-time-picker>
          </el-form-item>

          <!-- 6 按年  -->
          <el-form-item
            prop="yearDay"
            v-if="form.jobCycle === '6'"
            label-width="0"
            style="margin-left: 30px"
          >
            <MonthDays
              v-model="form.yearDay"
              :monthDaysOptions="monthDaysOptions"
              @getValue="getYearValue"
            />
          </el-form-item>

          <el-form-item
            prop="cycleYear"
            v-if="form.jobCycle === '6'"
            label-width="0"
          >
            <el-time-picker
              v-model="form.cycleYear"
              :picker-options="pickerOptions"
              placeholder="请选择时间"
              value-format="HH:mm"
              format="HH:mm"
              @change="checkValidate('cycleYear')"
            >
            </el-time-picker>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </common-edit-dialog>
</template>

<script>
import { assetsScanAdd, assetsScanEdit } from "@/api/analysisCenter/assetsScan";
import ContentTip from "@/views/analysisCenter/log/ContentTip/index.vue";
import { domainIPSeg, domainPortSeg } from "@/utils/formRules";
import MonthDays from "month-days-element";
import { CYCLESHORTARR } from "@/utils/constant";
import { validateIPOrNull, validateDomainOrNull } from "@/utils/formValidates";
export default {
  components: {
    ContentTip,
    MonthDays,
  },
  props: {},
  watch: {
    "form.jobCycle"(val) {
      //定时
      if (val === "1") {
        this.rules = { ...this.rulesBasic, ...this.rules1 };
      }
      //按日
      if (val === "2") {
        this.rules = { ...this.rulesBasic, ...this.rules2 };
      }
      //按周
      if (val === "3") {
        this.rules = { ...this.rulesBasic, ...this.rules3 };
      }
      //按月
      if (val === "4") {
        this.rules = { ...this.rulesBasic, ...this.rules4 };
      }
      //按季
      if (val === "5") {
        this.rules = { ...this.rulesBasic, ...this.rules5 };
      }
      //按年
      if (val === "6") {
        this.rules = { ...this.rulesBasic, ...this.rules6 };
      }
    },
  },

  data() {
    const validateIPs = (rule, value, callback) => {
      if (value === "" || typeof value === "undefined" || value == null) {
        callback(new Error());
      } else {
        let values = value.split(",");
        const ipv4s_1 = new RegExp(
          "^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])-(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$"
        );
        const ipv4s_2 = new RegExp(
          "^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$"
        );
        const ipv6 = new RegExp(
          "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"
        );
        values.map((item) => {
          if (ipv4s_1.test(item) || ipv4s_2.test(item) || ipv6.test(item)) {
            callback();
          } else {
            callback(new Error());
          }
        });
      }
    };
    return {
      buttonLoading: false,
      title: "",
      open: false,
      rules: {},
      rulesBasic: {
        scanType: [
          { required: true, message: "请选择扫描方式", trigger: "change" },
        ],
        nmapName: [
          { required: true, message: "请输入任务名称", trigger: "change" },
        ],
        nmapIps: [
          { required: true, message: "请输入IP段", trigger: "blur" },
          {
            required: true,
            message: "IP格式错误，支持IPV4/IPV6格式",
            validator: validateIPs,
            trigger: "blur",
          },
        ],
        nmapPorts: domainPortSeg,
        jobCycle: [
          { required: true, message: "请选择执行周期", trigger: "blur" },
        ],
      },
      executionCycleTypeArr: CYCLESHORTARR,
      pickerOptions: {
        selectableRange: "00:00:00 - 23:59:59",
      },
      pickerTimeOptions: {
        disabledDate(current) {
          return (
            current.getTime() <
            new Date(new Date().setHours(0, 0, 0, 0)).getTime()
          );
        },
      },
      monthDaysOptions: {
        placeholder: "请选择", // 占位内容，默认为选择日期
        size: "small", // 输入框尺寸 large, small, mini 默认large
        clearable: true, // 是否显示清除按钮，默认true
        disabled: false, // 禁用，默认false
        readonly: false, // 只读，默认false
        popperClass: "", // 弹出框类名
      },

      form: {
        nmapName: "",
        scanType: "0",
        nmapIps: "",
        nmapPorts: "",
        jobCycle: "",

        cycleTime: "", // 定时时间 yyyy-MM-dd HH:mm:ss
        cycleDay: "", //按日 HH:mm

        weekDay: "", //按周  周几
        cycleWeek: "", //按周 时间 HH:mm

        monthDay: "", //按月 几号
        cycleMonth: "", //按月 时间

        quarterDay: "", //按季 月日
        cycleQuarter: "", //按季 时间

        yearDay: "", //按年 月日
        cycleYear: "", //按年 时间
      },

      rules1: {
        cycleTime: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (value) {
                let now = new Date().getTime();
                if (new Date(value).getTime() - now > 0) {
                  callback();
                } else {
                  callback(new Error("执行时间必须大于当前时间"));
                }
              } else {
                callback(new Error("请选择"));
              }
            },
            trigger: ["blur", "change"],
          },
        ],
      },
      rules2: {
        cycleDay: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
      },
      rules3: {
        weekDay: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
        cycleWeek: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
      },
      rules4: {
        monthDay: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
        cycleMonth: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
      },

      rules5: {
        quarterDay: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
        cycleQuarter: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
      },

      rules6: {
        yearDay: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
        cycleYear: [
          {
            required: true,
            message: "请选择",
            trigger: ["blur", "change"],
          },
        ],
      },
    };
  },
  methods: {
    checkValidate(key) {
      this.$refs["form"].validateField(key);
    },
    changeType(val) {
      this.form.cycleTime = "";
      this.form.cycleDay = "";
      this.form.weekDay = "";
      this.form.cycleWeek = "";
      this.form.monthDay = "";
      this.form.cycleMonth = "";
      this.form.quarterDay = "";
      this.form.cycleQuarter = "";
      this.form.yearDay = "";
      this.form.cycleYear = "";
    },
    show(data) {
      this.title = data.id ? "编辑资产扫描" : "新增资产扫描";
      this.open = true;
      this.rules = this.rulesBasic;
      this.form = data.id ? data : this.$options.data().form;
    },

    getQuarterValue(val) {
      this.form.quarterDay = val;
      this.checkValidate("quarterDay");
    },

    getYearValue(val) {
      this.form.yearDay = val;
      this.checkValidate("yearDay");
    },

    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          let params = {
            nmapName: this.form.nmapName,
            scanType: this.form.scanType,
            nmapIps: this.form.nmapIps,
            nmapPorts: this.form.nmapPorts,
            type: "DATASCAN",
            jobCycle: this.form.jobCycle,
          };

          let others = {};
          if (this.form.jobCycle === "1") {
            others = {
              cycleTime: this.form.cycleTime,
            };
          } else if (this.form.jobCycle === "2") {
            others = {
              cycleDay: this.getParamTime(this.form.cycleDay),
            };
          } else if (this.form.jobCycle === "3") {
            others = {
              weekDay: this.form.weekDay,
              cycleWeek: this.getParamTime(this.form.cycleWeek),
            };
          } else if (this.form.jobCycle === "5") {
            others = {
              quarterDay: this.form.quarterDay,
              cycleQuarter: this.getParamTime(this.form.cycleQuarter),
            };
          } else if (this.form.jobCycle === "6") {
            others = {
              yearDay: this.form.yearDay,
              cycleYear: this.getParamTime(this.form.cycleYear),
            };
          }

          if (this.form.jobCycle === "4") {
            others = {
              monthDay: this.form.monthDay,
              cycleMonth: this.getParamTime(this.form.cycleMonth),
            };

            if (
              +others.monthDay === 29 ||
              +others.monthDay === 30 ||
              +others.monthDay === 31
            ) {
              this.$confirm(
                "某些月份不足" +
                  others.monthDay +
                  "天，对于这些月份，执行将被安排到该月的最后一天",
                "警告",
                {
                  confirmButtonText: "确定",
                  cancelButtonText: "取消",
                  type: "warning",
                }
              ).then(() => {
                this.handleAddOrEdit(params, others);
              });
            } else {
              this.handleAddOrEdit(params, others);
            }
          } else {
            this.handleAddOrEdit(params, others);
          }
        }
      });
    },

    getParamTime(time) {
      return time.split(":").length === 2 ? time + ":00" : time;
    },

    handleAddOrEdit(params, others) {
      this.buttonLoading = true;
      if (this.form.id) {
        this.handleEdit(params, others);
      } else {
        this.handleAdd(params, others);
      }
    },

    handleAdd(params, others) {
      assetsScanAdd({ ...params, ...others })
        .then((res) => {
          if (res && res.code === 200) {
            this.$emit("submitForm");
            this.$GlobalSuccessMessage("保存成功");
            this.open = false;
          } else {
            this.$GlobalErrorConfirm("保存失败", res.msg);
          }
        })
        .catch(() => {})
        .finally(() => {
          this.buttonLoading = false;
        });
    },

    handleEdit(params, others) {
      assetsScanEdit({
        ...params,
        ...others,
        ...{ id: this.form.id, status: "1" },
      })
        .then((res) => {
          if (res && res.code === 200) {
            this.$emit("submitForm");
            this.$GlobalSuccessMessage("编辑成功");
            this.open = false;
          } else {
            this.$GlobalErrorConfirm("编辑失败", res.msg);
          }
        })
        .catch(() => {})
        .finally(() => {
          this.buttonLoading = false;
        });
    },

    cancel() {
      this.open = false;
    },
  },
};
</script>

<style lang="scss" scoped>
.taskItem {
  ::v-deep .el-form-item__content {
    width: calc(100% - 90px) !important;
    display: flex;
  }
}
.by-day-execute {
  margin-left: 30px;
  width: 100%;
}
::v-deep .mouth-days-value {
  width: 96% !important;
}
</style>
